package com.ruoyi.common.utils.encry;

import javax.crypto.Cipher;
import javax.crypto.NoSuchPaddingException;
import javax.crypto.SecretKey;
import javax.crypto.spec.OAEPParameterSpec;
import javax.crypto.spec.PSource;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.security.KeyFactory;
import java.security.NoSuchAlgorithmException;
import java.security.PrivateKey;
import java.security.PublicKey;
import java.security.spec.MGF1ParameterSpec;
import java.security.spec.PKCS8EncodedKeySpec;
import java.security.spec.X509EncodedKeySpec;
import java.util.Base64;

public class RSAUtils {
    // 加载RSA密钥
    private static PublicKey loadPublicKey(String filename) throws Exception {
        String publicKeyContent = new String(Files.readAllBytes(Paths.get(filename)))
                .replaceAll("\\n", "")
                .replaceAll("\\r", "")
                .replace("-----BEGIN PUBLIC KEY-----", "")
                .replace("-----END PUBLIC KEY-----", "");
        byte[] decoded = Base64.getDecoder().decode(publicKeyContent);
        X509EncodedKeySpec keySpec = new X509EncodedKeySpec(decoded);
        KeyFactory keyFactory = KeyFactory.getInstance("RSA");
        return keyFactory.generatePublic(keySpec);
    }

    // 加载RSA私钥（示例代码，实际需从安全位置读取）
    private static PrivateKey loadPrivateKey() throws Exception {
//        System.out.println(System.getProperty("user.dir"));
        String privateKeyContent = new String(Files.readAllBytes(Paths.get("./key/private_key.pem")))
                .replaceAll("\\n", "")
                .replaceAll("\\r", "")
                .replace("-----BEGIN PRIVATE KEY-----", "")
                .replace("-----END PRIVATE KEY-----", "");
        byte[] decoded = Base64.getDecoder().decode(privateKeyContent);
        PKCS8EncodedKeySpec keySpec = new PKCS8EncodedKeySpec(decoded);
        KeyFactory keyFactory = KeyFactory.getInstance("RSA");
        return keyFactory.generatePrivate(keySpec);
    }

    public static byte[] decryPtion(String content) throws Exception {
        OAEPParameterSpec oaepParams = new OAEPParameterSpec(
                "SHA-256",
                "MGF1",
                MGF1ParameterSpec.SHA256,
                PSource.PSpecified.DEFAULT
        );

        byte[] encryptedAesKey = Base64.getDecoder().decode(content);
        Cipher rsaCipher = Cipher.getInstance("RSA/ECB/OAEPWithSHA-256AndMGF1Padding");
        rsaCipher.init(Cipher.DECRYPT_MODE, loadPrivateKey(), oaepParams);
        byte[] aesKeyBytes = rsaCipher.doFinal(encryptedAesKey);
        return aesKeyBytes;
    }

    // RSA 加密
    public static String rsaEncryPtion(SecretKey aesKey){
        OAEPParameterSpec oaepParams = new OAEPParameterSpec(
                "SHA-256",
                "MGF1",
                MGF1ParameterSpec.SHA256,
                PSource.PSpecified.DEFAULT
        );

        PublicKey serverPublicKey;
        try {
            serverPublicKey = loadPublicKey("./key/public_key.pem");
            Cipher rsaCipher = Cipher.getInstance("RSA/ECB/OAEPWithSHA-256AndMGF1Padding");
            rsaCipher.init(Cipher.ENCRYPT_MODE, serverPublicKey, oaepParams);
            byte[] encryptedAesKey = rsaCipher.doFinal(aesKey.getEncoded());
            return Base64.getEncoder().encodeToString(encryptedAesKey);
        } catch (Exception e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
            return "";
        }

    }
}
